package side_server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

public class Server implements Runnable{
	public final static String 		SEP = "_SEP_";
	private static Server 			instance;
	private String					ip;
	private int						port;
	private String					localfolder;
	private ServerSocket			svrSocket;
	private Socket					cliSocket;
	private HashSet<String>			addresses;
	private HashMap<String, Socket> sockets;
	
	public static Server getInstance()
	{
		if(instance==null) instance=new Server();
		return instance;
	}
	
	public Server()
	{
		super();
		ip="";
		port=0;
		localfolder="";
		addresses = new HashSet<String>();
		sockets   = new HashMap<String, Socket>();
	}

	public void setPort(int port)
	{
		this.port=port;
	}
	
	public void setLocalFolder(String localfolder)
	{
		this.localfolder = localfolder;
	}
	
	private boolean initServer()
	{
		try {
			svrSocket=new ServerSocket(port);
			return true;
		} catch (IOException e) {
			System.out.println("ERRORE DURANTE LA CREAZIONE DEL SERVER SULLA PORTA " + port);
			return false;
		}
	}
	
	private void waitForConnection()
	{
		System.out.println("************************");
		System.out.println("* PAGANET v 0.6.6 beta *");
		System.out.println("************************");
		
		while(true)
		{
			try {
				cliSocket = new Socket();
				cliSocket = svrSocket.accept();
				ip = cliSocket.getLocalAddress().getHostAddress(); // my IP
				String address = getAddressFromSocket(cliSocket);
				addresses.add(address);
				sockets.put(address, cliSocket);
				showPeers();
				ServerConnection svrConn =  new ServerConnection(cliSocket, "wait");
				new Thread(svrConn).start();
			}
			catch (IOException e) {
				System.out.println("CONNESSIONE PERSA");
			}
		}
	}
	
	public String getAddressFromSocket(Socket socket)
	{
		//String ip   = socket.getInetAddress().getHostAddress();
		//int    port = socket.getLocalPort();
		return ip + " " + port;
	}
	
	public HashSet<String> getAddressSet()
	{
		return addresses;
	}
	
	public String getIp()
	{
		return this.ip;
	}
	
	public int getPort()
	{
		return this.port;
	}
	
	public String getServerAddress()
	{
		return this.ip + " " + this.getPort();
	}
	
	public String getPeerList() //return the peerlist in text format
	{
		Iterator<String> it = addresses.iterator();
		String peerlist = "";
		while(it.hasNext())
		{
			peerlist += it.next() + SEP;
		}
		return peerlist;
	}
	
	public HashSet<String> getPeerSet() //return the peerlist in hashset format
	{
		return addresses;
	}
	
	public String getLocalFolder()
	{
		return this.localfolder;
	}
	
	public Socket getSocket(String address)
	{
		return sockets.get(address);
	}
	
	public void addSocket(String address,Socket socket)
	{
		sockets.put(address, socket);
	}
	
	public void removeSocket(String address)
	{
		sockets.remove(address);
	}
	
	public HashMap<String, Socket> getSockets()
	{
		return sockets;
	}
	
	public void showPeers()
	{
		Iterator<String> it;
		it=addresses.iterator();
		System.out.println("\n\nELENCO PEERS");
		System.out.println("=================");
		while (it.hasNext())
		{
			System.out.println(it.next());
		}
		System.out.println("=================\n\n");
	}
	
	@Override
	public void run() 
	{
		if(initServer()) waitForConnection();
	}
}
